/*
 * 描述： TU HOST2HOST模擬服務端
 * 修改人： Weng.weng
 * 修改时间： 2021年10月26日
 * 项目： test
 */
package com.aeasycredit;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * TU HOST2HOST模擬服務端<br>
 * 執行示例：java com.aeasycredit.TuHost2HostMockServer D:/response_tuef.txt
 * 
 * @author Weng.weng
 * @version [版本号, 2021年10月26日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class TuHost2HostMockServer {
	
	private static final int SERVER_PORT = 26001;
	
	private static final char RECORD_END_CHAR = (char)19;
	
	private static final int THREAD_POOL_SIZE = 20;
	
	private static final String RESPONSE_TUEF_FILE_PATH = "/tmp/response_tuef.txt";

	public static void main(String[] args) throws IOException {
		
		final String finalFilePath = getResponseContentFilePath(args);
		System.out.println("filePath:" + finalFilePath);
		
		ServerSocket server = new ServerSocket(SERVER_PORT);
		System.out.println("server start...");
		
		ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
		while (true) {

			Socket socket = server.accept();
			Runnable runnable=()->{
				try (InputStream inputStream = socket.getInputStream();
						OutputStream outputStream = socket.getOutputStream();){
			        String inputContent = readContentFromInputStream(inputStream);
			        System.out.println("[client]: " + inputContent);
					
			        String outputContent = readFile(finalFilePath);
			        writeContentToOutputStream(outputStream, outputContent);
				} catch (Exception e) {
					e.printStackTrace();
				}
			};
			threadPool.submit(runnable);
		}
	}

	/**
	 * 
	 * 從輸入流中讀取內容<br>
	 * 遇到特定結束符則停止讀取並返回讀取的內容
	 *
	 * @param inputStream 輸入流
	 * @return String 讀取的內容
	 * @throws IOException
	 * @version [版本号, 2021年10月26日]
	 * @author Weng.weng
	 */
	private static String readContentFromInputStream(InputStream inputStream) throws IOException {
		byte[] bytes = new byte[1024];
		int len;
		StringBuilder stringBuilder = new StringBuilder();
		while ((len = inputStream.read(bytes)) != -1) {
			
			String str = new String(bytes, 0, len, "UTF-8");
			stringBuilder.append(str);

			int endIndex = str.indexOf(RECORD_END_CHAR);
			if (endIndex >= 0) {
				break;
			}
		}
		return stringBuilder.toString();
	}
	
	/**
	 * 
	 * 把内容寫入輸出流<br>
	 *
	 * @param outputStream 輸出流
	 * @param content 内容
	 * @throws IOException
	 * @version [版本号, 2021年10月26日]
	 * @author Weng.weng
	 */
	private static void writeContentToOutputStream(OutputStream outputStream, String content) throws IOException {
        outputStream.write(content.getBytes("UTF-8"));
        outputStream.flush();
	}
	
	/**
	 * 
	 * 從指定文件中讀取内容<br>
	 *
	 * @param filePath 文件全路徑
	 * @return String 文件内容
	 * @throws IOException
	 * @version [版本号, 2021年10月26日]
	 * @author Weng.weng
	 */
	private static String readFile(String filePath) throws IOException {
		Path path = Paths.get(filePath);
		String str = "";
		if (Files.exists(path)) {
			byte[] bytes = Files.readAllBytes(path);
			str = new String(bytes, 0, bytes.length, "UTF-8");
		}
		
		return str;
	}
	
	/**
	 * 
	 * 模擬響應内容所在的文件全路徑<br>
	 *
	 * @param args 參數數組
	 * @return String 文件全路徑
	 * @version [版本号, 2021年10月26日]
	 * @author Weng.weng
	 */
	private static String getResponseContentFilePath(String[] args) {
		String filePath = RESPONSE_TUEF_FILE_PATH;
		if (args != null && args.length >= 1) {
			filePath = args[0];
		}
		return filePath;
	}
	
}
